
#include "usart.h"

/* printf重定向 */
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, ch);
    while (!USART_GetFlagStatus(USART1, USART_FLAG_TXE));
    return ch;
}

//=======================================================USART1=======================================================
/* USART1初始化 */
void USART1_Init(uint32_t baud)
{
    // 使能USART1和GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    // 配置USART1的TX引脚(PA9)为复用推挽输出
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1的RX引脚(PA10)为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = baud;                                      // 设置波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     // 设置数据位为8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          // 设置停止位为1位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             // 设置无校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 设置无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 // 设置为收发模式
    USART_Init(USART1, &USART_InitStructure);

    // 使能USART1接收中断
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    
    // 配置NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;           // 设置USART1中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;   // 设置抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;          // 设置响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // 使能中断通道
    NVIC_Init(&NVIC_InitStructure);

    // 使能USART1
    USART_Cmd(USART1, ENABLE);
}

/* USART1发送字节数据 */
void USART1_SendByte(uint8_t byte)
{
    USART_SendData(USART1, byte);
    while (!USART_GetFlagStatus(USART1, USART_FLAG_TXE));
}

/* USART1中断服务函数 */
void USART1_IRQHandler(void)
{
    if (USART_GetITStatus(USART1, USART_IT_RXNE))   // 判断是否接收到数据
    {
        USART1_SendByte(USART_ReceiveData(USART1));
        
        USART_ClearITPendingBit(USART1, USART_IT_RXNE); // 清除接收中断标志
    }
}
//=======================================================USART1=======================================================

//=======================================================USART2=======================================================
/* USART2初始化 */
void USART2_Init(uint32_t baud)
{
    // 使能USART2和GPIOA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 配置USART2的TX引脚(PA2)为复用推挽输出
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART2的RX引脚(PA3)为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART2
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = baud;                                      // 设置波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     // 设置数据位为8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          // 设置停止位为1位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             // 设置无校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 设置无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 // 设置为收发模式
    USART_Init(USART2, &USART_InitStructure);

    // 使能USART2接收中断
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    
    // 配置NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;           // 设置USART2中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;   // 设置抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;          // 设置响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // 使能中断通道
    NVIC_Init(&NVIC_InitStructure);

    // 使能USART2
    USART_Cmd(USART2, ENABLE);
}

/* USART2发送字节数据 */
void USART2_SendByte(uint8_t byte)
{
    USART_SendData(USART2, byte);
    while (!USART_GetFlagStatus(USART2, USART_FLAG_TXE));
}

/* USART2中断服务函数 */
void USART2_IRQHandler(void)
{
    if (USART_GetITStatus(USART2, USART_IT_RXNE))   // 判断是否接收到数据
    {
        USART2_SendByte(USART_ReceiveData(USART2));
        
        USART_ClearITPendingBit(USART2, USART_IT_RXNE); // 清除接收中断标志
    }
}
//=======================================================USART2=======================================================

//=======================================================USART3=======================================================
/* USART3初始化 */
void USART3_Init(uint32_t baud)
{
    // 使能USART3和GPIOB时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    // 配置USART3的TX引脚(PB10)为复用推挽输出
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置USART3的RX引脚(PB11)为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置USART3
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = baud;                                      // 设置波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     // 设置数据位为8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          // 设置停止位为1位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             // 设置无校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 设置无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 // 设置为收发模式
    USART_Init(USART3, &USART_InitStructure);

    // 使能USART3接收中断
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
    
    // 配置NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;           // 设置USART3中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;   // 设置抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          // 设置响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // 使能中断通道
    NVIC_Init(&NVIC_InitStructure);

    // 使能USART3
    USART_Cmd(USART3, ENABLE);
}

/* USART3发送字节数据 */
void USART3_SendByte(uint8_t byte)
{
    USART_SendData(USART3, byte);
    while (!USART_GetFlagStatus(USART3, USART_FLAG_TXE));
}

/* USART3中断服务函数 */
void USART3_IRQHandler(void)
{
    if (USART_GetITStatus(USART3, USART_IT_RXNE))   // 判断是否接收到数据
    {
        USART3_SendByte(USART_ReceiveData(USART3));
        
        USART_ClearITPendingBit(USART3, USART_IT_RXNE); // 清除接收中断标志
    }
}
//=======================================================USART3=======================================================
